package com.xs.gis.util;

import org.geotools.referencing.CRS;
import org.opengis.parameter.ParameterValueGroup;
import org.opengis.referencing.ReferenceIdentifier;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.crs.ProjectedCRS;

/**
 * @program: cdgis_geotoolsplus
 * @description:
 * @author: w
 * @create: 2024-03-07 17:49
 **/
public class CRSUtils {

    public static final String CGCS2000 = "CGCS2000";
    public static final String Beijing54 = "Beijing 1954";
    public static final String Beijing = "New Beijing";
    public static final String Xian80 = "Xian 1980";
    public static final String UTM_SPLIT = "zone ";

    public static void main(String[] args) {
        //            String code=getCRS(39559047.43599, 3977293.67339,CGCS2000);
        String code = getCRSByUTM(CGCS2000, "39");
        System.out.println(code);

    }

    static int[] codes = {
            //WGS 84
            3857,
            //CGCS2000
            4512, 4511, 4510, 4509, 4508, 4507, 4506, 4505, 4504, 4503, 4502, 4501, 4500, 4499, 4498, 4497, 4496, 4495, 4494, 4493, 4492, 4491,
            4554, 4553, 4552, 4551, 4550, 4549, 4548, 4547, 4546, 4545, 4544, 4543, 4542, 4541, 4540, 4539, 4538, 4537, 4536, 4535, 4534,
            4533, 4532, 4531, 4530, 4529, 4528, 4527, 4526, 4525, 4524, 4523, 4522, 4521, 4520, 4519, 4518, 4517, 4516, 4515, 4514, 4513,
            //Beijing 1954
            21463, 21462, 21461, 21460, 21459, 21458, 21457, 21456, 21455, 21454, 21453,
            21423, 21422, 21421, 21420, 21419, 21418, 21417, 21416, 21415, 21414, 21413,
            2442, 2441, 2440, 2439, 2438, 2437, 2436, 2435, 2434, 2433, 2432, 2431, 2430, 2429, 2428, 2427, 2426, 2425, 2424, 2423, 2422,
            2421, 2420, 2419, 2418, 2417, 2416, 2415, 2414, 2413, 2412, 2411, 2410, 2409, 2408, 2407, 2406, 2405, 2404, 2403, 2402, 2401,
            //New Beijing
            4589, 4588, 4587, 4586, 4585, 4584, 4583, 4582, 4581, 4580, 4579,
            4578, 4577, 4576, 4575, 4574, 4573, 4572, 4571, 4570, 4569, 4568,
            4822, 4812, 4800, 4799, 4798, 4797, 4796, 4795, 4794, 4793, 4792, 4791, 4790, 4789, 4788, 4787, 4786, 4785, 4784, 4783, 4782,
            4781, 4780, 4779, 4778, 4777, 4776, 4775, 4774, 4773, 4772, 4771, 4770, 4769, 4768, 4767, 4766, 4756, 4755, 4754, 4753, 4753,
            //Xian 80
            2348, 2347, 2346, 2345, 2344, 2343, 2342, 2341, 2340, 2339, 2338,
            2337, 2336, 2335, 2334, 2333, 2332, 2331, 2330, 2329, 2328, 2327,
            2390, 2389, 2388, 2387, 2386, 2385, 2384, 2383, 2382, 2381, 2380, 2379, 2378, 2377, 2376, 2375, 2374, 2373, 2372, 2371, 2370,
            2369, 2368, 2367, 2366, 2365, 2364, 2363, 2362, 2361, 2360, 2359, 2358, 2357, 2356, 2355, 2354, 2353, 2352, 2351, 2350, 2349,
    };


    /**
     * 方法描述: 获取投影坐标系
     */
    public static String getCRSByUTM(String crsName, String utm) {
        String utmZoneString = "25";

        for (int code : codes) {
            try {
                String epsgCode = "EPSG:" + code;
                CoordinateReferenceSystem crs = CRS.decode(epsgCode);
                ReferenceIdentifier name = crs.getName();
                String nameCode = name.getCode();
                int utmZoneIndex = nameCode.indexOf(UTM_SPLIT);
                if (utmZoneIndex != -1) {
                    // 解析 UTM 带号
                    utmZoneString = nameCode.substring(utmZoneIndex + UTM_SPLIT.length(), nameCode.length());
                }
                if (nameCode.startsWith(crsName) && utm.equals(utmZoneString)) {
                    return epsgCode;
                }
            } catch (Exception e) {
            }
        }
        return null;
    }


    /**
     * 通过坐标得到epsgCode
     *
     * @param x       经度
     * @param crsName 参考系
     * @return epscCode
     */
    public static String getCRS(double x, String crsName, Double degree) {
        for (int code : codes) {
            try {
                String epsgCode = "EPSG:" + code;
                CoordinateReferenceSystem crs = CRS.decode(epsgCode);
                ProjectedCRS projectedCRS = CRS.getProjectedCRS(crs);
                if (projectedCRS == null) {
                    continue;
                }
                ParameterValueGroup parameterValues = projectedCRS.getConversionFromBase().getParameterValues();
                double centralMeridian = parameterValues.parameter("central_meridian").doubleValue();

                if (centralMeridian - (degree / 2) <= x && centralMeridian + (degree / 2) >= x) {
                    String nameCode = crs.getName().getCode();
                    if (nameCode.startsWith(crsName)) {
                        return epsgCode;
                    }
                }
            } catch (Exception e) {
            }
        }
        return null;
    }

    /***
     *  通过最大坐标最小坐标获得计算带宽 得到code
     * @param minx 最小经度
     * @param maxx 最大经度
     * @param crsName 参考系
     * @return epscCode
     */
    public static String getCRS(double minx, double maxx, String crsName) {
        double degree = getDegree(minx, maxx);
        return getCRS((minx + degree) / 2, crsName, degree);
    }


    /**
     * @param minx 经度
     * @param maxx 最大精度
     * @return
     */
    public static double getDegree(double minx, double maxx) {
        double degree = maxx - minx;
        if (Math.abs(degree) > 3) {
            return 6;
        } else {
            return 3;
        }

    }


}
